/**
 * Test of Closure function
 *
 * author: Marcin Wachulski
 *
 */
#include "OKTest.h"

// checks whether all elements in sub set are included within super set
bool subsumes(AttributeSet *sub, AttributeSet *super) {
    for (std::set<Attribute>::iterator i = sub->data.begin();
        i != sub->data.end(); i++)
        if (super->data.find(*i) == super->data.end())
            return false;
    return true;
}

class ClosureTest : public testing::Test {
protected:
    virtual void SetUp() {
        AttributeSet *attrSet;
        ObjectSet *objSet;

        attrSet = new AttributeSet();
        attrSet->data.insert(104);
        objSet = new ObjectSet();
        objSet->data.insert(1);
        fc.data.push_back(OAPair(objSet, attrSet));

        attrSet = new AttributeSet();
        attrSet->data.insert(103);
        objSet = new ObjectSet();
        objSet->data.insert(1);
        objSet->data.insert(2);
        fc.data.push_back(OAPair(objSet, attrSet));

        attrSet = new AttributeSet();
        attrSet->data.insert(102);
        objSet = new ObjectSet();
        objSet->data.insert(1);
        objSet->data.insert(2);
        objSet->data.insert(3);
        fc.data.push_back(OAPair(objSet, attrSet));

        attrSet = new AttributeSet();
        attrSet->data.insert(101);
        objSet = new ObjectSet();
        objSet->data.insert(1);
        objSet->data.insert(2);
        objSet->data.insert(3);
        objSet->data.insert(4);
        fc.data.push_back(OAPair(objSet, attrSet));

        fc.processedNo = 4;

        attrSet = new AttributeSet();
        attrSet->data.insert(107);
        objSet = new ObjectSet();
        objSet->data.insert(1);
        fc.data.push_back(OAPair(objSet, attrSet));

        attrSet = new AttributeSet();
        attrSet->data.insert(105);
        objSet = new ObjectSet();
        objSet->data.insert(1);
        objSet->data.insert(2);
        fc.data.push_back(OAPair(objSet, attrSet));

        attrSet = new AttributeSet();
        attrSet->data.insert(108);
        objSet = new ObjectSet();
        objSet->data.insert(1);
        objSet->data.insert(2);
        objSet->data.insert(3);
        fc.data.push_back(OAPair(objSet, attrSet));

        attrSet = new AttributeSet();
        attrSet->data.insert(106);
        attrSet->data.insert(116);
        attrSet->data.insert(126);
        objSet = new ObjectSet();
        objSet->data.insert(1);
        objSet->data.insert(2);
        objSet->data.insert(3);
        objSet->data.insert(4);
        fc.data.push_back(OAPair(objSet, attrSet));

        prefix.data.insert(0);
        prefix.data.insert(2);
        prefix.data.insert(4);
        prefix.data.insert(6);
        prefix.data.insert(8);
    }

    FormalContext fc;
    AttributeSet prefix;
};

TEST_F(ClosureTest, no_processing) {
    AttributeSet attrSet;
    unsigned int attrs_num = attrSet.data.size();
    ObjectSet objSet;

    Closure(prefix, OAPair(&objSet, &attrSet), fc);

    EXPECT_EQ(prefix.data.size() + attrs_num, attrSet.data.size());
    subsumes(&prefix, &attrSet);
    EXPECT_EQ(8, fc.data.size());
    EXPECT_EQ(4, fc.processedNo);
    EXPECT_TRUE(is_sorted(fc));
}

TEST_F(ClosureTest, nonequal_support) {
    AttributeSet attrSet;
    attrSet.data.insert(1);
    attrSet.data.insert(2);
    attrSet.data.insert(3);
    unsigned int attrs_num = attrSet.data.size();
    ObjectSet objSet;

    Closure(prefix, OAPair(&objSet, &attrSet), fc);

    EXPECT_EQ(7, attrSet.data.size());
    subsumes(&prefix, &attrSet);
    EXPECT_EQ(8, fc.data.size());
    EXPECT_EQ(4, fc.processedNo);
    EXPECT_TRUE(is_sorted(fc));
}

TEST_F(ClosureTest, full_processing) {
    AttributeSet attrSet;
    attrSet.data.insert(1);
    attrSet.data.insert(2);
    attrSet.data.insert(3);
    attrSet.data.insert(4);
    attrSet.data.insert(5);
    attrSet.data.insert(1001);
    unsigned int attrs_num = attrSet.data.size();
    ObjectSet objSet;
    objSet.data.insert(3);
    objSet.data.insert(4);
    objSet.data.insert(5);
    objSet.data.insert(6);

    AttributeSet last_attrSet_inFC = *(fc.data.back().second);

    Closure(prefix, OAPair(&objSet, &attrSet), fc);

    EXPECT_EQ(12, attrSet.data.size());
    subsumes(&prefix, &attrSet);
    subsumes(&last_attrSet_inFC, &attrSet);
    EXPECT_EQ(7, fc.data.size());
    EXPECT_EQ(4, fc.processedNo);
    EXPECT_TRUE(is_sorted(fc));
}
